//! 端到端测试工具函数
//!
//! 提供端到端测试的通用工具和辅助函数

use std::sync::Arc;
use std::collections::HashMap;
use data_gateway_kernel::{DataGatewayKernel, Query, QueryType};
use data_gateway_kernel::query::{QueryOptions, QueryContext};
use data_gateway_parser::{ScriptParser, ScriptExecutor, ScriptContext};
use data_gateway_data_sources::DataSourceManager;
use data_gateway_query_engine::QueryEngine;
use serde_json::{json, Value};
use data_gateway_parser::Value as ParserValue;

/// 创建测试用的内核实例
pub async fn create_test_kernel() -> anyhow::Result<Arc<DataGatewayKernel>> {
    let kernel = Arc::new(DataGatewayKernel::new().await?);
    kernel.start().await?;
    Ok(kernel)
}

/// 执行测试脚本
pub async fn execute_test_script(script: &str) -> anyhow::Result<Value> {
    let mut parser = ScriptParser::new();
    let program = parser.parse(script)?;

    let context = ScriptContext::new();
    let mut executor = ScriptExecutor::new(context);
    let result = executor.execute(program).await?;

    // 转换ParserValue到serde_json::Value
    let json_value = match result.value {
        ParserValue::Integer(n) => Value::Number(n.into()),
        ParserValue::Float(f) => Value::Number(serde_json::Number::from_f64(f).unwrap_or_else(|| 0.into())),
        ParserValue::String(s) => Value::String(s),
        ParserValue::Boolean(b) => Value::Bool(b),
        ParserValue::Null => Value::Null,
        ParserValue::Array(arr) => {
            let json_arr: Vec<Value> = arr.into_iter().map(|v| match v {
                ParserValue::Integer(n) => Value::Number(n.into()),
                ParserValue::Float(f) => Value::Number(serde_json::Number::from_f64(f).unwrap_or_else(|| 0.into())),
                ParserValue::String(s) => Value::String(s),
                ParserValue::Boolean(b) => Value::Bool(b),
                ParserValue::Null => Value::Null,
                _ => Value::Null,
            }).collect();
            Value::Array(json_arr)
        }
        ParserValue::Object(_) => Value::Null, // 简化处理
        ParserValue::DateTime(_) => Value::Null, // 简化处理
        ParserValue::Binary(_) => Value::Null, // 简化处理
    };

    Ok(json_value)
}

/// 创建测试数据
pub fn create_test_data(count: usize) -> Vec<Value> {
    (0..count).map(|i| {
        json!({
            "id": i + 1,
            "name": format!("User{}", i + 1),
            "age": 20 + (i % 50),
            "email": format!("user{}@example.com", i + 1),
            "active": if i % 2 == 0 { "true" } else { "false" }
        })
    }).collect()
}

/// 创建测试查询
pub fn create_test_query(id: &str, query_type: QueryType, content: &str) -> Query {
    Query {
        id: id.to_string(),
        query_type,
        content: content.to_string(),
        parameters: HashMap::new(),
        options: QueryOptions::default(),
        context: QueryContext::default(),
    }
}



/// 测试数据转换性能
pub async fn test_data_conversion_performance(data: &[Value]) -> anyhow::Result<()> {
    let mut engine = QueryEngine::new();

    let start_time = std::time::Instant::now();

    // 将JSON数据转换为HashMap格式
    let table_data: Vec<HashMap<String, Value>> = data.iter()
        .map(|item| {
            if let Value::Object(obj) = item {
                obj.iter().map(|(k, v)| (k.clone(), v.clone())).collect()
            } else {
                HashMap::new()
            }
        })
        .collect();

    // 创建内存表
    engine.create_memory_table("test_table", table_data).await?;

    let conversion_time = start_time.elapsed();
    println!("数据转换时间: {:?} ({}行)", conversion_time, data.len());

    // 验证表已创建
    let tables = engine.list_tables();
    assert!(tables.contains(&"test_table".to_string()));

    Ok(())
}

/// 端到端测试环境
pub struct E2ETestEnvironment {
    pub kernel: Arc<DataGatewayKernel>,
    pub data_source_manager: DataSourceManager,
    pub query_engine: QueryEngine,
}

impl E2ETestEnvironment {
    /// 创建新的端到端测试环境
    pub async fn new() -> anyhow::Result<Self> {
        let kernel = create_test_kernel().await?;
        let mut data_source_manager = DataSourceManager::new();
        data_source_manager.initialize_default_sources().await?;
        let query_engine = QueryEngine::new();

        Ok(Self {
            kernel,
            data_source_manager,
            query_engine,
        })
    }

    /// 执行完整的数据查询流程测试
    pub async fn test_full_query_pipeline(&mut self, test_data: Vec<Value>) -> anyhow::Result<()> {
        // 1. 准备测试数据
        let table_data: Vec<HashMap<String, Value>> = test_data.iter()
            .map(|item| {
                if let Value::Object(obj) = item {
                    obj.iter().map(|(k, v)| (k.clone(), v.clone())).collect()
                } else {
                    HashMap::new()
                }
            })
            .collect();

        // 2. 创建内存表
        self.query_engine.create_memory_table("users", table_data).await?;

        // 3. 执行SQL查询
        let query = create_test_query(
            "e2e_test",
            QueryType::Sql,
            "SELECT name, age FROM users WHERE age > 25 ORDER BY age"
        );

        let result = self.query_engine.execute(query).await?;

        // 4. 验证查询结果
        assert!(result.is_success(), "查询应该成功");

        // 5. 执行脚本查询
        let script_result = execute_test_script("var x = 42; x * 2;").await?;
        assert_eq!(script_result, Value::Number(84.into()));

        Ok(())
    }

    /// 清理测试环境
    pub async fn cleanup(&mut self) -> anyhow::Result<()> {
        self.data_source_manager.disconnect_all().await?;
        self.kernel.stop().await?;
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn test_create_test_kernel() {
        let kernel = create_test_kernel().await.unwrap();
        // 简化测试，不检查具体状态
        kernel.stop().await.unwrap();
    }

    #[tokio::test]
    async fn test_execute_test_script() {
        let result = execute_test_script("var x = 10; x + 5;").await.unwrap();
        assert_eq!(result, Value::Number(15.into()));
    }

    #[tokio::test]
    async fn test_create_test_query() {
        let query = create_test_query("test", QueryType::Sql, "SELECT 1");
        assert_eq!(query.id, "test");
        assert_eq!(query.query_type, QueryType::Sql);
        assert_eq!(query.content, "SELECT 1");
    }

    #[tokio::test]
    async fn test_data_conversion_performance_wrapper() {
        let test_data = create_test_data(100);
        test_data_conversion_performance(&test_data).await.unwrap();
    }

    #[tokio::test]
    async fn test_e2e_environment() {
        let mut env = E2ETestEnvironment::new().await.unwrap();

        let test_data = create_test_data(10);
        env.test_full_query_pipeline(test_data).await.unwrap();

        env.cleanup().await.unwrap();
    }

    #[tokio::test]
    async fn test_full_query_pipeline_with_large_dataset() {
        let mut env = E2ETestEnvironment::new().await.unwrap();

        // 测试大数据集
        let test_data = create_test_data(1000);
        env.test_full_query_pipeline(test_data).await.unwrap();

        env.cleanup().await.unwrap();
    }

    #[tokio::test]
    async fn test_script_and_sql_integration() {
        let mut env = E2ETestEnvironment::new().await.unwrap();

        // 测试脚本执行
        let script_result = execute_test_script("var users = 100; users * 2;").await.unwrap();
        assert_eq!(script_result, Value::Number(200.into()));

        // 测试SQL查询
        let test_data = create_test_data(50);
        let table_data: Vec<HashMap<String, Value>> = test_data.iter()
            .map(|item| {
                if let Value::Object(obj) = item {
                    obj.iter().map(|(k, v)| (k.clone(), v.clone())).collect()
                } else {
                    HashMap::new()
                }
            })
            .collect();

        env.query_engine.create_memory_table("test_users", table_data).await.unwrap();

        let query = create_test_query(
            "integration_test",
            QueryType::Sql,
            "SELECT COUNT(*) as total FROM test_users"
        );

        let result = env.query_engine.execute(query).await.unwrap();
        assert!(result.is_success());

        env.cleanup().await.unwrap();
    }
}
